#include <iostream>
#include <stdio.h>
#include <string.h>
#include <limits>

using std::cout;
using std::endl;
using std::cin;

class String 
{
public:
	String()
    : _pstr( new char[1]{'\0'} )
    {
        cout<<"无参构造"<<endl;
    }

	String(const char *a)
    : _pstr(new char[strlen(a) + 1 ])
    {
        cout<<"有参构造"<<endl;
        strcpy(_pstr,a);
    }

	String(const String &str)
    : _pstr(new char[strlen(str._pstr)+1])
    {
        cout<<"拷贝构造"<<endl;
        strcpy(_pstr,str._pstr);
    }

    ~String(){
        if(_pstr){
            delete []_pstr;
            _pstr=nullptr;
        }
        cout<<"析构"<<endl;
    }


    String &operator=(const String &rhs)
    {
        cout<<"赋值运算符函数，参数为c++风格"<<endl;
        if(&rhs!=this){
            _pstr=new char[strlen(rhs._pstr)+1];
            strcpy(_pstr,rhs._pstr);
        }
        return *this;
    }

    String &operator=(const char *a)
    {
        cout<<"赋值运算符函数，参数为c风格"<<endl;
        _pstr=new char[strlen(a)+1];
        strcpy(_pstr,a);
        return *this;
    }

    String &operator+=(const String &rhs)
    {
        //不能使用string直接相加，因为这是String类
        cout<<"+=，参数为c++风格"<<endl;
        char *result=new char[strlen(rhs._pstr)+strlen(_pstr)+1];
        strcpy(result,_pstr);
        strcat(result,rhs._pstr);
        _pstr=result;
        return *this;
    }
	String &operator+=(const char *a)
    {
        cout<<"+=，参数为c风格"<<endl;
        char *result=new char[strlen(_pstr)+strlen(a)+1];
        strcpy(result,_pstr);
        strcat(result,a);
        _pstr=result;
        return *this;

    }

	char &operator[](std::size_t index)
    {
        cout<<"可以修改返回的字符"<<endl;
        if(index<strlen(_pstr))
            return _pstr[index];
        else{
            static char nullchar='\0';
            return nullchar;
        }
    }

	const char &operator[](std::size_t index) const
    {
        cout<<"不允许修改返回的字符"<<endl;
        if(index<strlen(_pstr))
            return _pstr[index];
        else{
            static char nullchar='\0';
            return nullchar;
        }
    }
	
	std::size_t size() const
    {
        return strlen(_pstr);
    }
	const char* c_str() const
    {
        return this->_pstr;
    }
	
	friend bool operator==(const String &, const String &);
	friend bool operator!=(const String &, const String &);
	
	friend bool operator<(const String &, const String &);
	friend bool operator>(const String &, const String &);
	friend bool operator<=(const String &, const String &);
	friend bool operator>=(const String &, const String &);
	
	friend std::ostream &operator<<(std::ostream &os, const String &s);
	friend std::istream &operator>>(std::istream &is, String &s);

    friend String operator+(const String &, const String &);
    friend String operator+(const String &, const char *);
    friend String operator+(const char *, const String &);

	char * _pstr;
};
bool operator==(const String &lhs, const String &rhs){
    if(lhs.size() == rhs.size())
        return true;
    else
        return false;
}
bool operator!=(const String &lhs, const String &rhs)
{
    if(lhs.size() != rhs.size())
        return true;
    else
        return false;
}


bool operator<(const String &lhs, const String &rhs){
    if(lhs.size() < rhs.size())
        return true;
    else
        return false;
}
bool operator>(const String &lhs, const String &rhs){

    if(lhs.size() > rhs.size())
        return true;
    else
        return false;
}

bool operator<=(const String &lhs, const String &rhs){

    if(lhs.size() <= rhs.size())
        return true;
    else
        return false;
}
bool operator>=(const String &lhs, const String &rhs){

    if(lhs.size() >= rhs.size())
        return true;
    else
        return false;
}

std::ostream &operator<<(std::ostream &os, const String &s){
    cout<<"重载输出流运算符"<<endl;
    if(s._pstr){
        os<<s._pstr;
    }
    else{
        static char nullchar='\0'; 
        os<<nullchar<<endl;
    }
    return os;
}

void readChar(std::istream &is, char *s){
    if(is>>s,!is.eof()){
        if(is.bad()){
            cout<<"stream is bad"<<endl;
            return;
        }
        else if(is.fail()){
            cin.clear();
            cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
            cout<<"请输入字符串"<<endl;
        }
        else 
            return;
    }

}

std::istream &operator>>(std::istream &is, String &s){
    //唯一的问题，这里输入是覆盖写
    cout<<"重载输入流运算符"<<endl;
    readChar(is,s._pstr);
    return is;
}

String operator+(const String &lhs, const String &rhs)
{   
    cout<<"c++风格 + c++风格"<<endl;
    String res;
    res._pstr=new char[strlen(lhs._pstr)+strlen(rhs._pstr)+1];
    //res._pstr=strcat(lhs._pstr, rhs._pstr);
    //这样就修改了lhs了，不对
    strcpy(res._pstr,lhs._pstr);
    strcat(res._pstr,rhs._pstr);
    return res;
    
}
String operator+(const String &lhs, const char *a)
{
    cout<<"c++风格 + c风格"<<endl;
    String res;
    res._pstr=new char[strlen(lhs._pstr)+strlen(a)+1];
    strcpy(res._pstr,lhs._pstr);
    strcat(res._pstr,a);
    return res;
}

String operator+(const char *a, const String &rhs)
{
    cout<<"c风格 + c++风格"<<endl;
    String res;
    res._pstr=new char[strlen(rhs._pstr)+strlen(a)+1];
    strcpy(res._pstr,a);
    strcat(res._pstr,rhs._pstr);
    return res;
}

void test(){
//~~~~~~~~~~~~~~~~~~~~~~~~~

    String s1;//无参构造
    // cout<<s1<<endl;  // 输入流右操作数为空，则什么都不打印，直接换行
    String s2="hello";//有参构造
    String s3(s2);//拷贝
    cout<<s3<<endl;

    //cout<<endl;
    //const char *a="world";
    //s1=a;
    s1=s2;
    cout<<(s2.size())<<endl;
    cout<<s1<<endl;
    
    cout<<endl;
    cin>>s3;
    cout<<s3<<endl;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    // +=
    printf("%s\n",(s1+=s2)._pstr);
    //printf("%s\n",(s1+=a)._pstr);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    // +
    //cout<<endl;
    //cout<<(s1+s2)._pstr<<endl;
    //cout<<(s1+a)._pstr<<endl;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
}

int main()
{   
    test();
    return 0;
}

